package com.itheima.service;

import com.itheima.entity.User;
import com.itheima.entity.UserDto;
import com.itheima.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import java.util.List;


@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    /**
     * CachePut：将方法返回值放入缓存
     * value：缓存的名称，每个缓存名称下面可以有多个key
     * key：缓存的key
     */
    @CachePut(value="userCache",key="#user.id") //key的生成：userCache::10
    public User insert(User user){
        userMapper.insert(user);
        return user;
    }
    /*
    启动服务,通过swagger接口文档测试，访问UserController的save()方法**
    因为id是自增，所以不需要设置id属性
    我们现在分别查看用户表和缓存中的数据，如果都能保存，则说明集成成功
    */

    /**
     * Cacheable：在方法执行前spring先查看缓存中是否有数据，如果有数据，则直接返回缓存数据；若没有数据，	  *调用方法并将方法返回值放到缓存中
     * value：缓存的名称，每个缓存名称下面可以有多个key
     * key：缓存的key
     */
    @Cacheable(cacheNames = "userCache",key = "#id")
    public User getById(Long id){
        User user = userMapper.getById(id);
        if(user == null){
            throw new RuntimeException("用户不存在");
        }
        return user;
    }
    /*
    重启服务,通过swagger接口文档测试，访问UserController的getById()方法
    第一次访问，会请求我们controller的方法，查询数据库。后面再查询相同的id，就直接从Redis中查询数据，不用再查询数据库了，就说明缓存生效了。
    测试步骤：
     - 提前在redis中手动删除掉id=${id}的用户数据
     - 查看控制台sql语句：说明从数据库查询的用户数据
     - 查看Redis中的缓存数据：说明已成功缓存
     - 再次查询相同id的数据时，直接从redis中直接获取，不再查询数据库。
     */


    /**
     * @CacheEvict：作用是清理指定缓存
     * value: 缓存的名称，每个缓存名称下面可以有多个key
     * key: 缓存的key  ----------> 支持Spring的表达式语言SPEL语法
     * @param id
     */
    @CacheEvict(value = "userCache",key = "#id")//删除某个key对应的缓存数据
    public void deleteById(Long id){
        userMapper.deleteById(id);
    }

    /**
     * @CacheEvict：作用是清理指定缓存
     * //cacheNames = "userCache" 删除userCache下所有的缓存数据
     */
    @CacheEvict(cacheNames = "userCache",allEntries = true)//删除userCache下所有的缓存数据
    public void deleteAll(){
        userMapper.deleteAll();
    }

    @Cacheable(value = "userCache",key = "#userDto.hashCode()")
    public List<User> getList(UserDto userDto){
        List<User> list = userMapper.getList("%" + userDto.getName() + "%", userDto.getAge());
        return list;
    }

/*
@Caching注解
作用: 组装其他缓存注解
- cacheable    组装一个或多个@Cacheable注解
- put    组装一个或多个@CachePut注解
- evict    组装一个或多个@CacheEvict注解
*/

}
